
package fr.mehfile.api.database;

import fr.mehfile.api.parser.CurrentNews;
import fr.mehfile.api.parser.Program;
import fr.mehfile.api.parser.Schedule;
import fr.mehfile.view.utils.Utils;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import java.net.URL;
import java.util.ArrayList;

public class DataBase extends SQLiteOpenHelper {
    public static final String TAG = "DataBase";

    private static final String NEWS_TABLE = "news";
    private static final String PROGRAM_TABLE = "program";
    private static final String SCHEDULE_TABLE = "schedule";
    private static final String DATABASE_NAME = "mehfile_zainab";

    private static final int DATABASE_VERSION = 1;
    private SQLiteDatabase db;

    private static final String COLUMN_ID = "id";
    private static final String COLUMN_TITLE = "title";
    private static final String COLUMN_CONTENT = "content";
    private static final String COLUMN_IMAGE_URL = "image_url";
    private static final String COLUMN_IMAGE_LOCATION = "image_location";
    private static final String COLUMN_DATE = "date";
    private static final String COLUMN_DESCRIPTION = "description";
    private static final String COLUMN_START_TIME = "start_time";
    private static final String COLUMN_END_TIME = "end_time";
    private static final String COLUMN_POSITION = "position";

    private static DataBase dataBase = null;

    private static final String CREATE_TABLE_NEWS =
            "create table " + NEWS_TABLE + "(" +
                    COLUMN_ID + " integer primary key autoincrement," +
                    COLUMN_TITLE + " text, " +
                    COLUMN_CONTENT + " text, " +
                    COLUMN_DATE + " text, " +
                    COLUMN_IMAGE_URL + " text, " +
                    COLUMN_IMAGE_LOCATION + " text);";

    private static final String CREATE_TABLE_PROGRAM =
            "create table " + PROGRAM_TABLE + "(" +
                    COLUMN_ID + " integer primary key autoincrement," +
                    COLUMN_DATE + " text, " +
                    COLUMN_TITLE + " text, " +
                    COLUMN_DESCRIPTION + " text, " +
                    COLUMN_POSITION + " integer);";

    private static final String CREATE_TABLE_SCHEDULE =
            "create table " + SCHEDULE_TABLE + "(" +
                    COLUMN_ID + " integer primary key autoincrement," +
                    COLUMN_START_TIME + " text, " +
                    COLUMN_END_TIME + " text, " +
                    COLUMN_TITLE + " text, " +
                    COLUMN_POSITION + " integer);";

    public static DataBase getInstance(Context context) {
        if (dataBase == null) {
            dataBase = new DataBase(context);
        }

        return dataBase;
    }

    /**
     * Constructor.
     * 
     * @param ctx le contexte de l'application.
     */
    private DataBase(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);

        Utils.debugger.logVerbose(TAG, "DataBase constructor");

        db = this.getReadableDatabase();
    }

    public void close() {
        super.close();
        db.close();
    }

    /**
     * Destructor.
     */
    @Override
    protected void finalize() throws Throwable {
        close();
        super.finalize();
    }

    /**
     * Creation of database.
     * 
     * @param db instance de la classe SQLiteDatabase
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        Utils.debugger.logVerbose("onCreate", "SQLiteDatabase");

        db.execSQL(CREATE_TABLE_NEWS);
        db.execSQL(CREATE_TABLE_PROGRAM);
        db.execSQL(CREATE_TABLE_SCHEDULE);
    }

    /**
     * Update Database.
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        initDB();
    }

    /**
     * Drop and recreate database.
     */
    public void initDB() {
        db.execSQL("DROP TABLE IF EXISTS " + CREATE_TABLE_NEWS);
        db.execSQL("DROP TABLE IF EXISTS " + CREATE_TABLE_PROGRAM);
        db.execSQL("DROP TABLE IF EXISTS " + CREATE_TABLE_SCHEDULE);
        onCreate(db);
    }

    public boolean startTransaction() {
        if (db != null) {
            db.beginTransaction();
            return true;
        } else {
            return false;
        }
    }

    public boolean endTransaction() {
        if (db != null) {
            db.endTransaction();
            return true;
        } else {
            return false;
        }
    }

    public boolean setTransactionSuccessfull() {
        if (db != null) {
            db.setTransactionSuccessful();
            return true;
        } else {
            return false;
        }
    }

    public ArrayList<NewsFromDatabase> getAllNews() {

        Cursor c = db.query(NEWS_TABLE, null, null, null, null, null, null);

        ArrayList<NewsFromDatabase> newsFromDatabase = new ArrayList<NewsFromDatabase>();

        if (c.moveToFirst()) {
            do {
                NewsFromDatabase currentNewsFromDataBase = new NewsFromDatabase();
                try {
                    currentNewsFromDataBase.setId(c.getInt(0));
                    currentNewsFromDataBase.setTitle(c.getString(1));
                    currentNewsFromDataBase.setContent(c.getString(2));
                    currentNewsFromDataBase.setDate(c.getString(3));
                    currentNewsFromDataBase.setImageUrl(new URL(c.getString(4)));
                    currentNewsFromDataBase.setImageLocation(c.getString(5));
                    newsFromDatabase.add(currentNewsFromDataBase);
                } catch (Exception e) {
                }
            } while (c.moveToNext());
        }

        c.close();

        return newsFromDatabase;
    }

    public ArrayList<ProgramFromDatabase> getAllPrograms() {

        Cursor c = db.query(PROGRAM_TABLE, null, null, null, null, null, null);

        ArrayList<ProgramFromDatabase> programsFromDatabase = new ArrayList<ProgramFromDatabase>();

        if (c.moveToFirst()) {
            do {
                ProgramFromDatabase currentProgramFromDataBase = new ProgramFromDatabase();
                try {
                    currentProgramFromDataBase.setId(c.getInt(0));
                    currentProgramFromDataBase.setDate(c.getString(1));
                    currentProgramFromDataBase.setTitle(c.getString(2));
                    currentProgramFromDataBase.setDescription(c.getString(3));
                    currentProgramFromDataBase.setPosition(c.getInt(4));
                    currentProgramFromDataBase
                            .setSchedules(getAllSchedules(currentProgramFromDataBase));
                    programsFromDatabase.add(currentProgramFromDataBase);
                } catch (Exception e) {
                }
            } while (c.moveToNext());
        }

        c.close();

        return programsFromDatabase;
    }

    public ArrayList<ScheduleFromDatabase> getAllSchedules(
            ProgramFromDatabase currentProgramFromDataBase) {

        String[] selectionArgs = {
                String.valueOf(currentProgramFromDataBase.getPosition())
        };

        Cursor c = db.query(SCHEDULE_TABLE, null, "position = ?", selectionArgs, null, null, null);

        ArrayList<ScheduleFromDatabase> schedulesFromDatabase = new ArrayList<ScheduleFromDatabase>();

        if (c.moveToFirst()) {
            do {
                ScheduleFromDatabase currentScheduleFromDatabase = new ScheduleFromDatabase();
                try {
                    currentScheduleFromDatabase.setId(c.getInt(0));
                    currentScheduleFromDatabase.setStart_time(c.getString(1));
                    currentScheduleFromDatabase.setEnd_time(c.getString(2));
                    currentScheduleFromDatabase.setTitle(c.getString(3));
                    currentScheduleFromDatabase.setPosition(c.getInt(4));
                    schedulesFromDatabase.add(currentScheduleFromDatabase);
                } catch (Exception e) {
                }
            } while (c.moveToNext());
        }

        c.close();

        return schedulesFromDatabase;
    }

    // public boolean needDefaultImages() {
    //
    // boolean result=true;
    // Cursor c = db.query(NEWS_TABLE, null, null, null, null, null, null);
    //
    //
    // if (c.moveToFirst()) {
    // do {
    // try {
    // if(c.getString(4)!=null ){
    // return false;
    // }
    // } catch (Exception e) {
    // }
    // } while (c.moveToNext());
    // }
    //
    // c.close();
    //
    // return true;
    // }

    public boolean insertNews(CurrentNews currentNews) {

        String title = currentNews.getTitle();
        String content = currentNews.getContent();
        String imageUrl = currentNews.getImage().toString();
        String date = currentNews.getDate();

        ContentValues values = new ContentValues();
        values.put(COLUMN_TITLE, title);
        values.put(COLUMN_CONTENT, content);
        values.put(COLUMN_IMAGE_URL, imageUrl);
        values.put(COLUMN_DATE, date);
        
        long id = db.insert(NEWS_TABLE, null, values);

        if (id != -1)
            return true;

        return false;
    }

    public boolean insertProgram(Program currentProgram, int index) {

        String date = currentProgram.getDate();
        String title = currentProgram.getTitle();
        String description = currentProgram.getDescription();

        ContentValues values = new ContentValues();
        values.put(COLUMN_DATE, date);
        values.put(COLUMN_TITLE, title);
        values.put(COLUMN_DESCRIPTION, description);
        values.put(COLUMN_POSITION, index);
        insertSchedules(currentProgram.getSchedules().getSchedule(), index);
        long id = db.insert(PROGRAM_TABLE, null, values);

        if (id != -1)
            return true;

        return false;
    }

    public boolean insertSchedules(ArrayList<Schedule> schedules, int id) {

        String startTime = null;
        String endTime = null;
        String title = null;
        Schedule currentSchedule = null;
        ContentValues values = new ContentValues();
        for (int i = 0; i < schedules.size(); i++) {
            currentSchedule = schedules.get(i);
            startTime = currentSchedule.getStart_time();
            endTime = currentSchedule.getEnd_time();
            title = currentSchedule.getTitle();

            values.put(COLUMN_START_TIME, startTime);
            values.put(COLUMN_END_TIME, endTime);
            values.put(COLUMN_TITLE, title);
            values.put(COLUMN_POSITION, id);

            db.insert(SCHEDULE_TABLE, null, values);
        }

        return true;
    }

    public void updateNews(NewsFromDatabase newsFromDatabase) {

        
        String imageLocation = newsFromDatabase.getImageLocation();

        Utils.debugger.logDebug(TAG, "update: ");

        ContentValues values = new ContentValues();

        if (imageLocation != null) {
            Utils.debugger.logDebug(TAG, "imageLocation: " + imageLocation);
            values.put(COLUMN_IMAGE_LOCATION, imageLocation);
        }

        String[] selectionArgs = {
                String.valueOf(newsFromDatabase.getId())
        };

        db.update(NEWS_TABLE, values, "id = ?", selectionArgs);

    }
    
    public void updateProgram(ProgramFromDatabase currentProgramFromDatabase,int index) {



        Utils.debugger.logDebug(TAG, "update: ");

        ContentValues values = new ContentValues();
        values.put(COLUMN_POSITION, index);
       

        String[] selectionArgs = {
                String.valueOf(currentProgramFromDatabase.getId())
        };

        db.update(PROGRAM_TABLE, values, "id = ?", selectionArgs);

    }
    
    public void updateSchedule(ScheduleFromDatabase currentScheduleFromDatabase, int index) {



        Utils.debugger.logDebug(TAG, "update: ");

        ContentValues values = new ContentValues();
        values.put(COLUMN_POSITION, index);
       

        String[] selectionArgs = {
                String.valueOf(currentScheduleFromDatabase.getId())
        };

        db.update(SCHEDULE_TABLE, values, "id = ?", selectionArgs);

    }

    public void deleteNews(NewsFromDatabase newsFromDatabase) throws Exception {
        String selection = COLUMN_ID + " = ?";
        String[] selectionArgs = {
                String.valueOf(newsFromDatabase.getId())
        };

        deleteNews(selection, selectionArgs);

    }

    private void deleteNews(String selection, String[] selectionArgs) throws Exception {
        db.delete(NEWS_TABLE, selection, selectionArgs);
    }

    public void deleteProgram(ProgramFromDatabase programFromDatabase) throws Exception {
        String selection = COLUMN_ID + " = ?";
        String[] selectionArgs = {
                String.valueOf(programFromDatabase.getId())
        };

        deleteProgram(selection, selectionArgs);
        deleteSchedule(programFromDatabase.getSchedules());

    }

    private void deleteProgram(String selection, String[] selectionArgs) throws Exception {
        db.delete(PROGRAM_TABLE, selection, selectionArgs);
    }

    public void deleteSchedule(ArrayList<ScheduleFromDatabase> scheduleFromDatabase)
            throws Exception {
        String selection = COLUMN_ID + " = ?";

        for (int i = 0; i < scheduleFromDatabase.size(); i++) {
            String[] selectionArgs = {
                    String.valueOf(scheduleFromDatabase.get(i).getId())
            };

            deleteSchedule(selection, selectionArgs);
        }

    }

    private void deleteSchedule(String selection, String[] selectionArgs) throws Exception {
        db.delete(SCHEDULE_TABLE, selection, selectionArgs);
    }
    
    public ProgramFromDatabase getProgramWithId(int id) {
       
        String[] selectionArgs = {
                String.valueOf(id)
        };

        Cursor c = db.query(PROGRAM_TABLE, null, "id = ?", selectionArgs, null, null, null);
        
        ProgramFromDatabase currentProgramFromDataBase = new ProgramFromDatabase();

        if (c.moveToFirst()) {
            do {
       
                try {
                    currentProgramFromDataBase.setId(c.getInt(0));
                    currentProgramFromDataBase.setDate(c.getString(1));
                    currentProgramFromDataBase.setTitle(c.getString(2));
                    currentProgramFromDataBase.setDescription(c.getString(3));
                    currentProgramFromDataBase.setPosition(c.getInt(4));
                    currentProgramFromDataBase
                            .setSchedules(getAllSchedules(currentProgramFromDataBase));
                } catch (Exception e) {
                }
            } while (c.moveToNext());
        }

        c.close();

        return currentProgramFromDataBase;
    }
    
    public void displayDatabaseContent(){
        Utils.debugger.logDebug(TAG, "************* NEWS TABLE *****************");
        ArrayList<NewsFromDatabase> newsFromDatabase= getAllNews();
        NewsFromDatabase currentNewsFromDatabase=null;
        for(int i=0; i<newsFromDatabase.size();i++){
            currentNewsFromDatabase= newsFromDatabase.get(i);
            Utils.debugger.logDebug(TAG, "Id: "+currentNewsFromDatabase.getId());
            Utils.debugger.logDebug(TAG, "Title: "+currentNewsFromDatabase.getTitle());
            Utils.debugger.logDebug(TAG, "Content: "+currentNewsFromDatabase.getContent());
            Utils.debugger.logDebug(TAG, "Image url: "+currentNewsFromDatabase.getImageUrl());
            Utils.debugger.logDebug(TAG, "Image location: "+currentNewsFromDatabase.getImageLocation());
            Utils.debugger.logDebug(TAG, "---------------------------------");
        }
        

        ArrayList<ProgramFromDatabase> programFromDatabase= getAllPrograms();
        ProgramFromDatabase currentProgramFromDatabase=null;
        for(int i=0; i<programFromDatabase.size();i++){
            Utils.debugger.logDebug(TAG, "************* PROGRAM TABLE *****************");
            currentProgramFromDatabase= programFromDatabase.get(i);
            Utils.debugger.logDebug(TAG, "Id: "+currentProgramFromDatabase.getId());
            Utils.debugger.logDebug(TAG, "Date: "+currentProgramFromDatabase.getDate());
            Utils.debugger.logDebug(TAG, "Title: "+currentProgramFromDatabase.getTitle());
            Utils.debugger.logDebug(TAG, "Description: "+currentProgramFromDatabase.getDescription());
            Utils.debugger.logDebug(TAG, "Position: "+currentProgramFromDatabase.getPosition());
            Utils.debugger.logDebug(TAG, "---------------------------------");
            
            Utils.debugger.logDebug(TAG, "************* SCHEDULE TABLE *****************");
            ArrayList<ScheduleFromDatabase> scheduleFromDatabasesFromDatabase= getAllSchedules(currentProgramFromDatabase);
            ScheduleFromDatabase currentScheduleFromDatabase=null;
            for(int j=0; j<scheduleFromDatabasesFromDatabase.size();j++){
                currentScheduleFromDatabase= scheduleFromDatabasesFromDatabase.get(j);
                Utils.debugger.logDebug(TAG, "Id: "+currentScheduleFromDatabase.getId());
                Utils.debugger.logDebug(TAG, "Start time: "+currentScheduleFromDatabase.getStart_time());
                Utils.debugger.logDebug(TAG, "End time: "+currentScheduleFromDatabase.getEnd_time());
                Utils.debugger.logDebug(TAG, "Title: "+currentScheduleFromDatabase.getTitle());
                Utils.debugger.logDebug(TAG, "Position: "+currentScheduleFromDatabase.getPosition());
                Utils.debugger.logDebug(TAG, "---------------------------------");
            }
        }
        
     
    }

}
